package elephant.service.rpc;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import elephant.Container;
import elephant.rpc.client.RPCClient;
import elephant.rpc.client.core.RPCMessageCallback;
import elephant.rpc.client.core.RPCServerInfo;
import elephant.service.Service;

/**
 * 
 * @author skydu
 *
 */
public class RPCClientService extends Service{
	//
	private static Logger logger=LoggerFactory.getLogger(RPCClientService.class);
	//
	private RPCClient client;
	//
	private List<RPCServerInfo> serverList;
	//
	public RPCClientService(){
		client=new RPCClient();
		serverList=new ArrayList<RPCServerInfo>();
	}
	//
	public void addRemoteServer(String cluster,String host,int port){
		if(cluster==null||cluster.length()==0){
			throw new IllegalArgumentException("cluster can not be null");
		}
		if(host==null||host.length()==0){
			throw new IllegalArgumentException("host can not be null");
		}
		for(RPCServerInfo info:serverList){
			if(info.cluster.equals(cluster)&&
					info.host.equals(host)&&info.port==port){
				throw new IllegalArgumentException("the same remoteserver.cluster:"+
						cluster+",host:"+host+",port:"+port);
			}
		}
		RPCServerInfo info=new RPCServerInfo(cluster, host, port);
		serverList.add(info);
		client.addRPCServerInfo(info);
	}
	//
	public <T> T createSyncRemote(Class<T> clazz,String cluster){
		return client.createSyncRemote(clazz,cluster);
	}
	
	public <T> T createAsyncRemote(Class<T> clazz,String cluster){
		return client.createAsyncRemote(clazz,cluster);
	}
	
	@Override
	public void init() throws Exception {
		if(logger.isInfoEnabled()){
			logger.info(getClass().getSimpleName()+" init");
		}
		client.init();
	}

	@Override
	public void start() throws Exception {
		if(logger.isInfoEnabled()){
			logger.info(getClass().getSimpleName()+" start");
		}
		client.setContextClassLoader(Container.get().getApplicationClassLoader());
		client.start();
	}

	@Override
	public void stop() throws Exception {
		if(logger.isInfoEnabled()){
			logger.info(getClass().getSimpleName()+" stop");
		}
	}
	//
	public void subscribe(String cluster,String topic){
		client.subscribe(cluster, topic);
	}
	//
	public void setPushMessageCallback(RPCMessageCallback pushMessageCallback) {
		client.setPushMessageCallback(pushMessageCallback);
	}
	/**
	 * @return the client
	 */
	public RPCClient getClient() {
		return client;
	}
	/**
	 * @param client the client to set
	 */
	public void setClient(RPCClient client) {
		this.client = client;
	}	
	/**
	 * 
	 * @param applicationClassLoader
	 */
	public void setContextClassLoader(ClassLoader contextClassLoader) {
		this.client.setContextClassLoader(contextClassLoader);	
	}
	//
	@Override
	public String dump() {
		return client.dump();
	}
	
}
